<?php

use Illuminate\Database\Capsule\Manager as DB;

#后台基类
abstract class McommonController extends CoreController
{
    protected $table;
    protected $model;
    protected $auth;
    protected $primaryKey= "id";
    protected $hiddens   = [];
    protected $appends   = [];
    protected $condition = [];
    protected $condition_in = [];
    protected $search = [];

    public function init()
    {
        parent::init();
        $this->checkAuth();
        $this->_view->assign('uniqid', uniqid('merchant'));
        $this->_view->assign('dianpu_id', $this->auth->dianpu_id);
    }

    #验证权限
    private function checkAuth()
    {
        $this->auth = new Auth(_RBACMerchantCookieKey_);
        if (!$this->auth->isLogin(true)) {
            redirect('/public/merchantlogin');
        }
        $this->checkRole();
    }

    private function checkRole()
    {
        #判断控制器&方法权限
        $allAuth = remember('merchant_auths_' . $this->auth->user_id, 3600, function () {
            $ownAuth = explode(',', DB::table('merchant_roles')->where('id', $this->auth->roles_id)->value('menu_ids'));
            $rows    = DB::table('merchant_menus')->whereIn('id', array_values($ownAuth))->where('actions', '<>', '')->whereNotNull('actions')->select('module', 'controller', 'actions')->get();
            $auth    = [];
            if ($rows->isNotEmpty()) {
                foreach ($rows as $k => $v) {
                    $allact = explode(',', $v->actions);
                    foreach ($allact as $action) {
                        array_push($auth, strtolower('/' . $v->module . '/' . $v->controller . '/' . $action));
                    }
                }
            }
            return $auth;
        });
        if (!in_array(strtolower('/' . $this->module . '/' . $this->controller . '/' . $this->action), $allAuth)) {
            throw new Exception('无访问权限.', 403);
        }
    }

    /**
     * @name 获取数据列表_基类
     * @param bool $returnData
     * @return array
     */
    #[获取数据列表_基类]
    public function indexAction($returnData = FALSE)
    {
        if($this->isPost()) {

            if(is_object($this->model)){
                $query = $this->model;
            }else{
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            if (!empty($this->search)) {
                $query = $query->where(function ($query) {
                    foreach ($this->search as $v) {
                        if (isset($v[3]) && strtolower($v[3]) == 'or') {
                            $query = $query->orWhere([$v]);
                        } else {
                            $query = $query->where([$v]);
                        }
                    }
                });
            }
            if (!empty($this->condition)) {
                $query = $query->where($this->condition);
            }
            if (!empty($this->condition_in)) {
                foreach ($this->condition_in as $k => $v) {
                    $query = $query->whereIn($v[0], $v[1]);
                }
            }
            $total = $query->count();
            $sort = $this->get('sort', 'sortorder');
            $order = $this->get('order', 'desc');
            $query = $query->orderBy($sort, $order)->orderBy($this->primaryKey, 'DESC');
            $page = $this->get('page');

            if (!empty($page)) {
                $limit = $this->get('rows', 10);
                $offset = ($page - 1) * $limit;
                $query = $query->offset($offset)->limit($limit);
            }
            $rows = $query->get();
            if(!empty($this->appends)){
                foreach ($this->appends as $append){
                    $rows = $rows->append($append);
                }
            }
            if(!empty($this->hiddens)){
                $rows = $rows->makeHidden($this->hiddens);
            }
            if ($returnData) {
                return ['total' => $total, 'rows' => $rows->toArray()];
            } else {
                json(['total' => $total, 'rows' => $rows]);
            }
        }else{
            $this->_view->display( strtolower($this->controller) . '/index.html');
        }
    }

    /**
     * @name 添加数据_基类
     */
    #[添加数据_基类]
    public function addAction()
    {
        if($this->isPost()) {
            do {
                $rows = $this->postData;
                $rows['created_at'] = date('Y-m-d H:i:s');
                unset($rows[$this->primaryKey], $rows['updated_at'], $rows['deleted_at']);
                $this->cleanColumn($rows);
                if(is_object($this->model)){
                    $query = $this->model;
                }else{
                    $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
                }
                if ($insert_id = $query->insertGetId($rows)) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                        'data' => $insert_id,
                    ];
                } else {
                    $result = [
                        'ret' => 3,
                        'msg' => '数据插入失败',
                    ];
                }
            } while (FALSE);
            json($result);
        }else{
            $this->_view->assign('dataset', json_encode($this->getTableColumn($this->table)));
            $this->_view->display( strtolower($this->controller) . '/edit.html');
        }
    }

    /**
     * @name 添加数据，返回新增ID
     * @return int
     */
    protected function insertGetId()
    {
        $rows               = $this->postData;
        $rows['created_at'] = date('Y-m-d H:i:s');
        $this->cleanColumn($rows);
        return DB::table($this->table)->insertGetId($rows);
    }

    /**
     * @name 编辑数据_基类
     * @param bool $returnData
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     * @throws Exception
     */
    #[编辑数据_基类]
    public function editAction()
    {
        if(is_object($this->model)){
            $query = $this->model;
        }else{
            $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
        }
        if($this->isPost()) {
            do {
                $rows = $this->postData;
                if (!isset($rows[$this->primaryKey]) && isset($rows['dataset']) && is_array($rows['dataset'])) {
                    $rows = $rows['dataset'];
                }
                $roles = [
                    $this->primaryKey => ['role' => "required|exists:{$this->table}.{$this->primaryKey}", 'msg' => '主键'],
                ];
                Validate::check($rows, $roles);
                $rows['updated_at'] = date('Y-m-d H:i:s');
                unset($rows['created_at'], $rows['deleted_at']);
                $this->cleanColumn($rows);
                if ($query->where($this->primaryKey, $rows[$this->primaryKey])->update($rows) !== FALSE) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                } else {
                    $result = [
                        'ret' => 3,
                        'msg' => '更新失败',
                    ];
                }
            } while (FALSE);
            json($result);
        }else{
            $id	= $this->get($this->primaryKey, 0);
            if($query->where($this->primaryKey,'=',$id)->doesntExist()){
                throw new Exception("记录不存在");
            }
            $query = $query->where($this->primaryKey,'=',$id)->first();
            if(!empty($this->appends)){
                foreach ($this->appends as $append){
                    $query = $query->append($append);
                }
            }
            $dataset = $query->toJson();
            $this->_view->assign('dataset', $dataset);
            $this->_view->display( strtolower($this->controller) . '/edit.html');
        }
    }

    /**
     * @name 清除多余字段
     */
    protected function cleanColumn(&$rows)
    {
        $columns = [];
        foreach (DB::select("SHOW COLUMNS FROM `{$this->config->database->prefix}{$this->table}`") as $v) {
            $columns[] = $v->Field;
        }
        foreach ($rows as $k => $v) {
            if (!in_array($k, $columns)) {
                unset($rows[$k]);
            }
        }
    }

    /**
     * @name 清除指定表多余字段
     */
    protected function cleanTableColumn($table, &$rows)
    {
        $columns = [];
        foreach (DB::select("SHOW COLUMNS FROM `{$this->config->database->prefix}{$table}`") as $v) {
            $columns[] = $v->Field;
        }
        foreach ($rows as $k => $v) {
            if (!in_array($k, $columns)) {
                unset($rows[$k]);
            }
        }
    }

    /**
     * @name 返回表的字段
     */
    protected function getTableColumn($table)
    {
        $columns = [];
        foreach (DB::select("SHOW COLUMNS FROM `{$this->config->database->prefix}{$table}`") as $v) {
            if (strstr($v->Type, 'int')) {
                $columns[$v->Field] = intval($v->Default) ?? 0;
            }elseif (strstr($v->Type, 'timestamp')) {
                $columns[$v->Field] = NULL;
            }else{
                $columns[$v->Field] = $v->Default ?? '';
            }
        }
        return $columns;
    }

    /**
     * @name 查看详情_基类
     * @param bool $returnData
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     */
    #[查看详情_基类]
    public function viewAction($returnData = FALSE)
    {
        $id = $this->get($this->primaryKey, 0);
        if (DB::table($this->table)->where($this->primaryKey, '=', $id)->doesntExist()) {
            ret(1, '记录不存在');
        }
        if(is_object($this->model)){
            $query = $this->model;
        }else{
            $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
        }
        $dataset = $query->where($this->primaryKey, '=', $id)->first();
        if ($returnData) {
            return $dataset;
        } else {
            ret(0, '记录详情', $dataset);
        }
    }

    /**
     * @name 删除数据_基类
     */
    #[回收数据_基类]
    public function deleteAction()
    {
        do {
            $id = $this->get($this->primaryKey, []);
            if (empty($id)) {
                $result = [
                    'ret' => 2,
                    'msg' => '参数为空',
                ];
                break;
            }
            if(is_object($this->model)){
                $query = $this->model;
            }else{
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            if (is_array($id)) {
                if ($query->whereIn($this->primaryKey, $id)->delete()) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            } elseif (is_numeric($id)) {
                if ($query->where($this->primaryKey, '=', $id)->doesntExist()) {
                    $result = [
                        'ret' => 4,
                        'msg' => '记录不存在',
                    ];
                    break;
                }
                if ($query->where($this->primaryKey, '=', $id)->delete()) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            }
            $result = [
                'ret' => '5',
                'msg' => '删除失败',

            ];
        } while (FALSE);
        json($result);
    }

    /**
     * @name 删除数据_基类
     */
    #[删除数据_基类]
    public function forceDeleteAction()
    {
        do {
            $id = $this->get($this->primaryKey, []);
            if (empty($id)) {
                $result = [
                    'ret' => 2,
                    'msg' => '参数为空',
                ];
                break;
            }
            if(is_object($this->model)){
                $query = $this->model;
            }else{
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            if (is_array($id)) {
                if ($query->whereIn($this->primaryKey, $id)->forceDelete()) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            } elseif (is_numeric($id)) {
                if ($query->where($this->primaryKey, '=', $id)->doesntExist()) {
                    $result = [
                        'ret' => 4,
                        'msg' => '记录不存在',
                    ];
                    break;
                }
                if ($query->where($this->primaryKey, '=', $id)->forceDelete()) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            }
            $result = [
                'ret' => '5',
                'msg' => '删除失败',

            ];
        } while (FALSE);
        json($result);
    }

    /**
     * @name 删除数据_基类
     */
    #[恢复数据_基类]
    public function restoreAction()
    {
        do {
            $id = $this->get($this->primaryKey, []);
            if (empty($id)) {
                $result = [
                    'ret' => 2,
                    'msg' => '参数为空',
                ];
                break;
            }
            if(is_object($this->model)){
                $query = $this->model;
            }else{
                $query = is_string($this->model) ? (new $this->model) : DB::table($this->table);
            }
            if (is_array($id)) {
                if ($query->whereIn($this->primaryKey, $id)->restore()) {
                    $result = [
                        'ret' => 0,
                        'msg' => '操作成功',
                    ];
                    break;
                }
            } elseif (is_numeric($id)) {
                if ($query->where($this->primaryKey, '=', $id)->first()->trashed()) {
                    $query->where($this->primaryKey, '=', $id)->restore();
                }
                $result = [
                    'ret' => 0,
                    'msg' => '操作成功',
                ];
                break;
            }
        } while (FALSE);
        json($result);
    }

}
